import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'
import { Observable } from 'rxjs'
import { NzMessageService } from 'ng-zorro-antd'
import { STColumn, STColumnBadge } from '@delon/abc'
import { SettingsService } from '@delon/theme'
import { I18NService } from '@core'
import { ListBaseClass } from '@shared/classes/ListBaseClass'
import { ISearchSchema, ISearchOption } from '@shared/interfaces/search'
import { ESearchType, ETransScene, EPaymentBrand } from '@shared/enums'
import { ITradeQueryParams, ITrade, ERevFlag, EProcFlag } from '@shared/interfaces/trade'
import {
  generatePaymentBrandOptions,
  generateTransSceneOptions,
  openDownloadDialog,
  signAmtNumberOfTrade,
} from 'app/utils/helpers'
import { TradeService } from '../trade-abstract.service'
import { EDateLimitEnum, Currency, IOption } from '@shared/interfaces/common'
import { today, TradeAmountMaxValue } from 'app/utils/contraints'
import { CurrencyService } from '@shared/services/currency.service'
import { AAMSFilterInit } from '@shared/interfaces/aams'
import { I18NPrefixWithPipe } from '@shared/filters/i18n-prefix-with.pipe'
import { Channel } from '@shared/interfaces/channel'
import { ChannelService } from '@shared/services/channel.service'
import { tap } from 'rxjs/operators'
import { DataService } from '@shared/services/data.service'
import { AmtFormatPipe } from '@shared/filters/amt-format.pipe'

const commonParams = {
  chanCode: '',
  currency: '',
  page: 1,
  size: 10,
  transScene: '',
}

@Component({
  selector: 'app-trades-batch-present-list',
  templateUrl: './present.component.html',
  styleUrls: [ './present.component.less', '../../../shared/styles/table.less' ],
})
export class TradesBatchPresentListComponent extends ListBaseClass<ITrade, ITradeQueryParams>
  implements OnInit, AAMSFilterInit {
  @ViewChild('transAmt') transAmt: TemplateRef<void>
  @ViewChild('insTpl') insTpl: TemplateRef<void>
  @ViewChild('agentTpl') agentTpl: TemplateRef<void>
  @ViewChild('merchantTpl') merchantTpl: TemplateRef<void>
  @ViewChild('storeTpl') storeTpl: TemplateRef<void>
  @ViewChild('tplCurrency') tplCurrency: TemplateRef<void>
  @ViewChild('tplTransScene') tplTransScene: TemplateRef<void>
  @ViewChild('tplChannel') tplChannel: TemplateRef<void>
  @ViewChild('checkTrans') checkTrans: TemplateRef<void>
  listOfSelection = [
    {
      text: 'Select All Row',
      onSelect: () => {
        this.checkAll(true)
      },
    },
  ]
  isAllDisplayDataChecked = false
  isIndeterminate = false
  listOfDisplayData: ITrade[] = []
  listOfAllData: ITrade[] = []
  mapOfCheckedId: { [key: string]: boolean } = {}
  TradeAmountMaxValue = TradeAmountMaxValue

  transAmtFrom: number // 交易金额从
  transAmtTo: number // 交易金额到

  selectedCurrency: Currency
  selectedChannelMerchant: Channel

  customSchema: ISearchSchema[] = []

  procFlagOptions: ISearchOption[] = []

  transSceneOptions: IOption[] = []
  selectedTransScene: ETransScene // 搜索交易场景
  selectedChannel: EPaymentBrand // 搜索渠道
  channelOptions$: Observable<ISearchOption[]>

  data: ITrade[] = []
  transData: ITrade[] = []
  currencyList$: Observable<Currency[]>
  insCode: string
  columns: STColumn[] = []

  math = Math // 引用使 html 可以调用

  normalProcBadge: STColumnBadge = {
    5: { text: this.trans('TRADE_STATUS.PENDING'), color: 'processing' },
    2: { text: this.trans('TRADE_STATUS.REJECT'), color: 'error' },
    0: { text: this.trans('TRADE_STATUS.RESOLVE'), color: 'success' },
  }
  procBadge: STColumnBadge = {
    ...this.normalProcBadge,
    '': { text: this.trans('GENERAL.INFO.UNKOWN'), color: 'error' },
    1: { text: this.trans('TRANS_SCENE.others'), color: 'error' },
    3: { text: this.trans('TRANS_SCENE.others'), color: 'error' },
    4: { text: this.trans('TRANS_SCENE.others'), color: 'error' },
  }

  constructor(
    public msg: NzMessageService,
    public i18n: I18NService,
    public router: Router,
    public route: ActivatedRoute,
    public settingService: SettingsService,
    private currencyService: CurrencyService,
    private tradeService: TradeService,
    private i18nPrefixWithPipe: I18NPrefixWithPipe,
    private channelService: ChannelService,
    private dataService: DataService,
    private amtFormatPipe: AmtFormatPipe,
  ) {
    super(msg, i18n, route, router, settingService)
    this.setDefaultParams(commonParams)
  }

  ngOnInit(): void {
    this.queryTableDataWithParams()
    this.initColumns()
    this.getInsCode()
    this.genTransSceneOptions()
    this.initStatusOptions()
    this.initialAAMSFilter()
  }

  initialAAMSFilter() {
    this.initAcquirer()
    this.initAgent()
    this.initMerchant()
    this.initStore()
  }

  getDecimalByCurrencyCode(currCode: string): Observable<number> {
    return this.currencyService.getDecimalByCode(currCode)
  }

  genTransSceneOptions(): void {
    this.transSceneOptions = generateTransSceneOptions().map(item => {
      item.label = this.i18nPrefixWithPipe.transform(item.value, 'TRANS_SCENE.')
      return item
    })
  }

  initColumns(): void {
    this.columns = [
      {
        type: 'link',
        title: '批次号',
        i18n: 'TRADE.BATCHNUM',
        index: 'orderNum',
        className: 'text-center',
        width: '150px',
        fixed: 'left',
        click: this.goDetail.bind(this),
      },
      {
        type: 'link',
        title: '订单号',
        i18n: 'TRADE.ORDER_NUM',
        index: 'orderNum',
        className: 'text-center',
        width: '150px',
        fixed: 'left',
        click: this.goDetail.bind(this),
      },
      {
        title: '门店名称',
        i18n: 'GENERAL.STORE.NAME',
        index: 'storeName',
        width: '150px',
        className: 'text-center',
      },
      {
        title: '终端编号',
        i18n: 'GENERAL.TERMINAL.CODE',
        className: 'text-center',
        width: '100px',
        render: 'transScene',
      },
      {
        title: '交易时间',
        i18n: 'TRADE.TRANS_TIME',
        index: 'createdAt',
        className: 'text-center',
        type: 'date',
        width: '150px',
        dateFormat: 'YYYY-MM-DD HH:mm',
      },
      {
        title: '交易金额',
        i18n: 'TRADE.TRANS_AMT',
        className: 'text-right p-sm',
        width: '100px',
        render: 'transAmt',
      },
      {
        title: '清算状态',
        i18n: 'GENERAL.INFO.STATUS',
        index: 'procFlag',
        type: 'badge',
        badge: this.procBadge,
        className: 'text-center',
        width: '100px',
      },
    ]
  }

  getInsCode(): void {
    const { insCode } = this.settingService.user
    this.insCode = insCode
  }

  initStatusOptions(): void {
    for (const key in this.normalProcBadge) {
      const option = { label: this.normalProcBadge[key].text, value: key }
      this.procFlagOptions.push(option)
    }
  }

  goDetail(record: ITrade): void {
    const { orderNum, intStoreCode, category } = record
    this.router.navigate([`../${orderNum}/${intStoreCode}/${category}`], { relativeTo: this.route })
  }

  queryTableDataWithParams(): void {
    this.loading = true
    const terminalid = this.route.snapshot.params['terminalid']
    const batchNum = this.route.snapshot.params['batchNum']
    const intStoreCode = this.route.snapshot.params['intStoreCode']
    const params = {
      page: 1,
      size: 1000,
      terminalId: terminalid
    }
    this.tradeService
      .getTransList(params, intStoreCode, batchNum)
      .subscribe(this.renderLists.bind(this), this.getListError.bind(this))
  }

  renderLists(res): void {
    const { data, total } = res
    this.transData = data
    this.transData = this.transData.filter(item => {
    return (
        !item.isManualsettled &&
        this.transScenceCheck(item.transScene) &&
        item.procFlag === EProcFlag.ProcSuccess &&
        !item.settFlag && (item.revFlag === ERevFlag.RevNormal || item.revFlag === ERevFlag.RevPartRefunded ||
           item.revFlag === ERevFlag.AdjustAmt || item.revFlag === ERevFlag.RevRefunded)
      )
    })
    this.total = total
    this.loading = false
  }

  transScenceCheck(transScene = '-'): boolean {
    const transSceneList = [
      'pos-MER', 'pos-MTH',
      'pos-MCR', 'pos-ACR',
      'pos-CJT', 'pos-CTH',
      'pos-PER', 'web-MER',
      'web-MTH',  'web-MCR'
     ]
    if (transSceneList.indexOf(transScene) !== -1) {
      return true
    }
    return false
  }

  currentPageDataChange($event): void {
    this.listOfDisplayData = $event
    this.refreshStatus()
  }

  refreshStatus(): void {
    this.isAllDisplayDataChecked = this.transData.every(item => this.mapOfCheckedId[item.orderNum])
    this.isIndeterminate =
      this.transData.some(item => this.mapOfCheckedId[item.orderNum]) && !this.isAllDisplayDataChecked
  }

  checkAll(value: boolean): void {
    this.transData.forEach(item => (this.mapOfCheckedId[item.orderNum] = value))
    this.refreshStatus()
  }

  next(): void {
    const url = this.router.url
    const originUrl = url.split(';')[0]
    const checkTransList = []
    this.transData.forEach(item => {
      if (this.mapOfCheckedId[item.orderNum]) {
        checkTransList.push(item)
      }
    })
    const manualTransList = []
    checkTransList.forEach(item => {
      this.amtFormatPipe.transformTransAmt(item.transAmt, item.currency).subscribe(value => {
        const manualTrans = {
          orderNum: item.orderNum,
          intStoreCode: item.intStoreCode,
          transAmt: parseFloat(value),
          operator: '',
          processType: 'MC1',
          remark: '',
        }
        manualTransList.push(manualTrans)
        this.dataService.setBatchPresentList(manualTransList)
      })
    })
    if (manualTransList.length === 0) {
      this.msg.error(this.trans('VALIDATION.REQUIRED_SELECT', { name: this.trans('BIZ.ACQUIRER.OTHER.TRADE') }))
      return
    }
    this.router.navigateByUrl(`${originUrl}/batchPresentDetail`)
  }

  goLeave(): void {
    const url = this.router.url
    const originUrl = url.split(';')[0]
    this.router.navigate(['../../../'], { relativeTo: this.route })
  }

  computeTransAmt(trade: ITrade): number {
    return signAmtNumberOfTrade(trade)
  }

  addZero(v) {
    return v < 10 ? '0' + v : v
  }

  switchTimeFormat(time) {
    const dateTime = new Date(time)
    const year = dateTime.getFullYear()
    const month = dateTime.getMonth() + 1
    const date = dateTime.getDate()
    const hour = dateTime.getHours()
    const minute = dateTime.getMinutes()
    const second = dateTime.getSeconds()
    return `${year}-${this.addZero(month)}-${this.addZero(date)} ${this.addZero(hour)}:${this.addZero(
      minute,
    )}:${this.addZero(second)}`
  }
}
